#include "stdafx.h"
#include "PPContextReadWriteHelper.h"
#include "LBProjPlanStream\LBProjPlanDataBase.h"
#include "utilityString.h"

namespace LBPROJ
{
    CPPContextReadWriteHelper::CPPContextReadWriteHelper(CPPContext* pContext)
        : m_pContext(pContext)
    {
    }


    CPPContextReadWriteHelper::~CPPContextReadWriteHelper()
    {
    }

    bool CPPContextReadWriteHelper::Open(LBPROJSTREAM::IProjPlanStreamDatabase * pDb)
    {
        ReadTask(pDb);
        ReadPreTask(pDb);
        return true;
    }

    bool CPPContextReadWriteHelper::Write(LBPROJSTREAM::IProjPlanStreamDatabase * pDb)
    {
        WriteTaskAndPreTask(pDb);
        return true;
    }

    bool CPPContextReadWriteHelper::ReadTask(LBPROJSTREAM::IProjPlanStreamDatabase * pDb)
    {
        std::list<ITask::Data> lstData;
        if (pDb->ReadTask(m_pContext->GetID(), lstData))
            m_pContext->GetTaskGroup()->DelAllItem();
        else
            return false;

        for (const auto& data : lstData)
        {
            CRefPtr<ITask> pTask = CreateTask(data.name, data.isMilestone);
            pTask->SetStart(data.start);
            pTask->SetFinish(data.finish);
            pTask->SetActualStart(data.actualStart);
            pTask->SetActualFinish(data.actualFinish);
            pTask->SetID(data.id);
            CRefPtr<ITask> pParent = m_pContext->GetTaskGroup()->FindTaskByID(data.parentId);
            if (pParent == nullptr)
                m_pContext->GetTaskGroup()->AddItem(pTask);
            else
                pParent->AddItem(pTask);
        }
        return true;
    }

    bool CPPContextReadWriteHelper::ReadPreTask(LBPROJSTREAM::IProjPlanStreamDatabase * pDb)
    {
        std::list<IPreTask::Data> lstPreTaskData;
        pDb->ReadPreTask(m_pContext->GetID(), lstPreTaskData);
        for (const auto& data : lstPreTaskData)
        {
            CRefPtr<ITask> pCurTask = m_pContext->GetTaskGroup()->FindTaskByID(data.currentTaskId);
            CRefPtr<ITask> pPreTaskTask = m_pContext->GetTaskGroup()->FindTaskByID(data.preTaskId);
            if (pCurTask == nullptr || pPreTaskTask == nullptr)
                continue;
            CRefPtr<IPreTask> pPreTask = CreatePreTask(static_cast<IPreTask::Type>(data.type), pPreTaskTask);
            pCurTask->GetPreTaskGroup()->AddItem(pPreTask);
        }
        return true;
    }

    bool CPPContextReadWriteHelper::WriteTaskAndPreTask(LBPROJSTREAM::IProjPlanStreamDatabase * pDb)
    {
        std::list<ITask::Data> lstData;
        std::list<IPreTask::Data> lstPreTaskData;
        int num = 1;
        CRefPtr<ITask> pTask;
        while ((pTask = m_pContext->GetTaskGroup()->FindTaskBySequence(num)) != nullptr)
        {
            ITask::Data taskData;
            pTask->Store(taskData);
            lstData.push_back(taskData);

            auto iter = pTask->GetPreTaskGroup()->CreateIterator();
            for (iter->First(); !iter->IsDone(); iter->Next())
            {
                IPreTask::Data preTaskData;
                iter->GetCurrentItem()->Store(preTaskData);
                lstPreTaskData.push_back(preTaskData);
            }

            num++;
        }
        pDb->WriteTask(m_pContext->GetID(), lstData);
        pDb->WritePreTask(m_pContext->GetID(), lstPreTaskData);
        return true;
    }

}
